import type { ParamsType } from '@ant-design/pro-provider';
import type { ProTableProps, RequestData, ProColumns } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table';
import type { ProCoreActionType, ProSchema, ProSchemaComponentTypes } from '@ant-design/pro-utils';
import { Space } from 'antd';
import React from 'react';

export interface XoProTableProps<T, U extends ParamsType, ValueType = 'text'>
  extends Omit<ProTableProps<T, U, ValueType>, 'request'> {
  /**
   * 操作列配置
   */
  optionButtonProps?: ProColumns<T, ValueType>;
  /**
   * 操作栏按钮
   */
  optionButtonRender?: (
    entity: T,
    index: number,
    action: ProCoreActionType | undefined,
    schema: ProSchema<T, unknown, ProSchemaComponentTypes, ValueType> & {
      isEditable?: boolean;
      type: ProSchemaComponentTypes;
    },
  ) => React.ReactNode;
  /**
   * 序号列配置
   */
  indexProps?: ProColumns<T, ValueType>;
  /**
   * 是否自动添加序号列
   */
  hasIndex?: boolean;
  request?: (
    params: U & {
      pageSize?: number;
      currentPage?: number;
      keyword?: string;
      export?: boolean;
    },
    filter: Record<string, React.ReactText[] | null>,
  ) => Promise<Partial<RequestData<T>>>;
}

/**
 * 二次封装的Protable
 * 将Protable请求参数中的`current`更换为`pageNumber`
 * @param props
 * @returns
 */
export function XoProTable<T, U extends ParamsType, ValueType = 'text'>(
  props: XoProTableProps<T, U, ValueType>,
) {
  const { indexProps, hasIndex, optionButtonRender, request, optionButtonProps } = props;
  const columns = [...(props.columns ?? [])];

  if (hasIndex && columns) {
    columns.unshift(
      Object.assign(
        {
          title: '序号',
          hideInSearch: true,
          key: 'id',
          valueType: 'index',
          width: 80,
          fixed: 'left',
        },
        indexProps,
      ),
    );
  }
  if (optionButtonRender) {
    columns?.push(
      Object.assign(
        {
          title: '操作',
          dataIndex: 'operation',
          fixed: 'right',
          width: 80,
          hideInSearch: true,
          render: (_: any, record: T, index: number, action: ProCoreActionType<{}> | undefined, schema: any) => {
            const result = optionButtonRender(record, index, action, schema);
            if (result) {
              return <Space size="small">{result}</Space>;
            }
            return undefined;
          },
        },
        optionButtonProps,
      ),
    );
  }
  return (
    <>
      <ProTable
        form={{
          ignoreRules: false,
        }}
        pagination={{
          showQuickJumper: true,
          showSizeChanger: true,
        }}
        {...props}
        columns={columns}
        request={
          request
            ? async (params, sort, filter) => {
              // 转换分页变量
              const { current } = params;
              delete params.current;
              const result = await request(
                {
                  currentPage: current,
                  ...params,
                },
                filter,
              );
              return result;
            }
            : undefined
        }
        toolBarRender={(action, rows) => {
          const result: React.ReactNode[] = [];
          if (props.toolBarRender) {
            result.push(...props.toolBarRender(action, rows));
          }
          return result;
        }}
      >
        {props.children}
      </ProTable>
    </>
  );
}

XoProTable.defaultProps = {
  hasIndex: true,
};
